"""
系统相关模型
"""
from sqlalchemy import Column, Integer, String, Boolean, DateTime, Text, ForeignKey, JSON, Float
from sqlalchemy.orm import relationship
from sqlalchemy.sql import func
from enum import Enum
from typing import Optional, Dict, Any

from .base import Base, TimestampMixin, ActiveMixin


class ConfigType(str, Enum):
    """配置类型枚举"""
    SYSTEM = "system"
    SECURITY = "security"
    EMAIL = "email"
    AI_SERVICE = "ai_service"
    AI_ANALYSIS_CONFIG = "ai_analysis_config"
    DATABASE = "database"
    NOTIFICATION = "notification"


class LogLevel(str, Enum):
    """日志级别枚举"""
    DEBUG = "debug"
    INFO = "info"
    WARNING = "warning"
    ERROR = "error"
    CRITICAL = "critical"


class OperationType(str, Enum):
    """操作类型枚举"""
    CREATE = "create"
    READ = "read"
    UPDATE = "update"
    DELETE = "delete"
    EXECUTE = "execute"
    DOWNLOAD = "download"
    UPLOAD = "upload"


class SystemConfig(Base, TimestampMixin, ActiveMixin):
    """系统配置模型"""
    
    __tablename__ = "system_config"
    
    # 配置信息
    config_key = Column(String(100), unique=True, index=True, nullable=False, comment="配置键")
    config_name = Column(String(200), nullable=False, comment="配置名称")
    config_type = Column(String(50), nullable=False, comment="配置类型")
    config_value = Column(JSON, comment="配置值")
    description = Column(Text, comment="配置描述")
    
    # 配置属性
    is_required = Column(Boolean, default=False, comment="是否必需")
    is_sensitive = Column(Boolean, default=False, comment="是否敏感")
    validation_rules = Column(JSON, comment="验证规则")
    
    # 分类和排序
    category = Column(String(50), comment="配置分类")
    sort_order = Column(Integer, default=0, comment="排序顺序")
    
    # 最后修改
    last_modified_by = Column(Integer, ForeignKey('user.id'), comment="最后修改人ID")
    last_modified_at = Column(DateTime, comment="最后修改时间")
    
    # 关系
    modifier = relationship("User", foreign_keys=[last_modified_by])
    
    def get_value(self, default=None):
        """获取配置值"""
        return self.config_value if self.config_value is not None else default
    
    def set_value(self, value, modified_by: int = None):
        """设置配置值"""
        self.config_value = value
        if modified_by is not None:
            self.last_modified_by = modified_by
        self.last_modified_at = func.now()
    
    def validate_value(self, value) -> bool:
        """验证配置值"""
        if not self.validation_rules:
            return True
        
        # 这里可以实现各种验证逻辑
        # 例如：类型检查、范围检查、格式检查等
        return True
    
    def to_dict(self, hide_sensitive: bool = True) -> dict:
        """转换为字典"""
        result = super().to_dict()
        if hide_sensitive and self.is_sensitive:
            result['config_value'] = "***"
        return result


class OperationLog(Base, TimestampMixin):
    """操作日志模型"""
    
    __tablename__ = "operation_log"
    
    # 操作信息
    operation_type = Column(String(50), nullable=False, comment="操作类型")
    operation_name = Column(String(100), nullable=False, comment="操作名称")
    resource_type = Column(String(50), comment="资源类型")
    resource_id = Column(String(100), comment="资源ID")
    
    # 操作者信息
    user_id = Column(Integer, ForeignKey('user.id'), comment="用户ID")
    username = Column(String(50), comment="用户名")
    user_role = Column(String(50), comment="用户角色")
    
    # 请求信息
    request_method = Column(String(10), comment="请求方法")
    request_path = Column(String(255), comment="请求路径")
    request_params = Column(JSON, comment="请求参数")
    request_body = Column(JSON, comment="请求体")
    
    # 响应信息
    response_status = Column(Integer, comment="响应状态")
    response_body = Column(JSON, comment="响应体")
    
    # 执行信息
    execution_time = Column(Float, comment="执行时长(秒)")
    ip_address = Column(String(45), comment="IP地址")
    user_agent = Column(String(255), comment="用户代理")
    
    # 结果信息
    status = Column(String(20), comment="状态")
    error_message = Column(Text, comment="错误信息")
    error_details = Column(JSON, comment="错误详情")
    
    # 关系
    user = relationship("User")
    
    def to_dict(self) -> dict:
        """转换为字典"""
        result = super().to_dict()
        return result


class SystemHealth(Base, TimestampMixin):
    """系统健康状态模型"""
    
    __tablename__ = "system_health"
    
    # 检查项目
    check_name = Column(String(100), nullable=False, comment="检查项目名称")
    check_type = Column(String(50), nullable=False, comment="检查类型")
    status = Column(String(20), nullable=False, comment="状态")
    
    # 检查结果
    result = Column(JSON, comment="检查结果")
    metrics = Column(JSON, comment="指标数据")
    
    # 性能数据
    response_time = Column(Float, comment="响应时间")
    success_rate = Column(Float, comment="成功率")
    error_count = Column(Integer, default=0, comment="错误数量")
    
    # 告警信息
    alert_level = Column(String(20), comment="告警级别")
    alert_message = Column(Text, comment="告警消息")
    
    # 检查时间
    check_time = Column(DateTime, default=func.now(), comment="检查时间")
    
    def to_dict(self) -> dict:
        """转换为字典"""
        result = super().to_dict()
        return result


class Notification(Base, TimestampMixin, ActiveMixin):
    """通知模型"""
    
    __tablename__ = "notification"
    
    # 通知信息
    title = Column(String(200), nullable=False, comment="通知标题")
    content = Column(Text, nullable=False, comment="通知内容")
    notification_type = Column(String(50), nullable=False, comment="通知类型")
    priority = Column(String(20), default="normal", comment="优先级")
    
    # 接收者
    user_id = Column(Integer, ForeignKey('user.id'), comment="接收用户ID")
    user_role = Column(String(50), comment="接收用户角色")
    
    # 发送状态
    status = Column(String(20), default="pending", comment="发送状态")
    send_time = Column(DateTime, comment="发送时间")
    read_time = Column(DateTime, comment="阅读时间")
    
    # 发送渠道
    channel = Column(String(50), comment="发送渠道")
    channel_config = Column(JSON, comment="渠道配置")
    
    # 关联
    related_resource_type = Column(String(50), comment="关联资源类型")
    related_resource_id = Column(String(100), comment="关联资源ID")
    
    # 关系
    user = relationship("User")
    
    def mark_as_sent(self):
        """标记为已发送"""
        self.status = "sent"
        self.send_time = func.now()
    
    def mark_as_read(self):
        """标记为已阅读"""
        self.status = "read"
        self.read_time = func.now()
    
    def to_dict(self) -> dict:
        """转换为字典"""
        result = super().to_dict()
        return result


class BackupRecord(Base, TimestampMixin):
    """备份记录模型"""
    
    __tablename__ = "backup_record"
    
    # 备份信息
    backup_name = Column(String(200), nullable=False, comment="备份名称")
    backup_type = Column(String(50), nullable=False, comment="备份类型")
    backup_size = Column(Integer, comment="备份大小")
    
    # 文件信息
    file_path = Column(String(500), nullable=False, comment="文件路径")
    file_name = Column(String(255), nullable=False, comment="文件名")
    file_hash = Column(String(64), comment="文件哈希")
    
    # 备份范围
    backup_scope = Column(JSON, comment="备份范围")
    backup_config = Column(JSON, comment="备份配置")
    
    # 状态
    status = Column(String(20), default="pending", comment="状态")
    start_time = Column(DateTime, comment="开始时间")
    end_time = Column(DateTime, comment="结束时间")
    duration = Column(Float, comment="持续时间(秒)")
    
    # 错误信息
    error_message = Column(Text, comment="错误信息")
    error_details = Column(JSON, comment="错误详情")
    
    # 创建者
    creator_id = Column(Integer, ForeignKey('user.id'), comment="创建者ID")
    
    # 关系
    creator = relationship("User")
    
    def start_backup(self):
        """开始备份"""
        self.status = "running"
        self.start_time = func.now()
    
    def complete_backup(self, file_path: str, file_name: str, backup_size: int = None):
        """完成备份"""
        self.status = "completed"
        self.end_time = func.now()
        self.file_path = file_path
        self.file_name = file_name
        
        if self.start_time:
            self.duration = (self.end_time - self.start_time).total_seconds()
        
        if backup_size is not None:
            self.backup_size = backup_size
        
        # 计算文件哈希
        import hashlib
        if backup_size and backup_size < 100 * 1024 * 1024:  # 小于100MB才计算哈希
            try:
                with open(file_path, 'rb') as f:
                    self.file_hash = hashlib.sha256(f.read()).hexdigest()
            except Exception:
                pass
    
    def fail_backup(self, error_message: str = None, error_details: Dict = None):
        """备份失败"""
        self.status = "failed"
        self.end_time = func.now()
        self.error_message = error_message
        self.error_details = error_details
        
        if self.start_time:
            self.duration = (self.end_time - self.start_time).total_seconds()
    
    def to_dict(self) -> dict:
        """转换为字典"""
        result = super().to_dict()
        return result